﻿using Little.Soldier;
using Little.Soldier.SWIFT.Validation;
using System.Collections.Generic;
using System.IO;

using System.Text.RegularExpressions;

namespace Little.Soldier.SWIFT
{
    public sealed class SwiftParser
    {
        private IReader iReader = new IReader();

        public static SwiftParser Instance
        {
            get
            {
                return SwiftParser._Instance._SwiftParser;
            }
        }

        private SwiftParser()
        {
        }

        public List<SwiftMessage> GetMessages(string messages, char messagesDelimiter, List<ValidationError> parseError)
        {
            return this.ListSwiftMessage(messages, messagesDelimiter, parseError);
        }

        public SwiftMessage GetMessage(string message, List<ValidationError> parseError)
        {
            return this.InternalSwiftMessage(message, parseError);
        }

        public string GetMessageAsText(SwiftMessage message)
        {
            StringWriter stringWriter = new StringWriter();
            new TextParser().WriteMessage(message, (TextWriter)stringWriter);
            return stringWriter.ToString();
        }

        public string GetMessageAsXml(SwiftMessage message)
        {
            return message.ToXml();
        }

        public string GetMessageAsXmlRaw(SwiftMessage message)
        {
            return message.ToXmlRaw();
        }

        public SwiftMessage GetMessageFromXml(string xml)
        {
            return SwiftXML.GetSwiftMessage(xml);
        }

        internal SwiftMessage InternalSwiftMessage(string message, List<ValidationError> parseError)
        {
            /* 
             * Acknowledgement
             * {1:F21VNDZBET2AXXX0015001466} Basic Header
             * {4:                           Text Block
             * {177:0106051534}
             * {451:0}}
            */

            Regex Acknowledgement = new Regex(@"((\x7B1:[A-Z0-9]+\x7D)(\x7B4:\x7B\w{3}:[\x7C\x7E\x7F\x0D\x0A\x20-\x7A]*\x7D+)(\x7B\w{3}:[\x7C\x7E\x7F\x0D\x0A\x20-\x7A]*\x7D+)*)");
            if (Acknowledgement.IsMatch(message))
            {
                Match match = Acknowledgement.Match(message);
                string MatchedValue = match.Value;
                message = message.Replace(MatchedValue, string.Empty);
            }

            this.iReader.Reader = (TextReader)new StringReader(message);
            SwiftMessage message1 = this.iReader.GetSwiftMessage(parseError);
            message1.Content = message;
            SwiftMessage swiftMessage = FinancialMessages.GetSwiftMessage(message1);
            swiftMessage.Validate(parseError);
            swiftMessage.Content = message;
            return swiftMessage;
        }

        internal List<SwiftMessage> ListSwiftMessage(string messages, char messagesDelimiter, List<ValidationError> parseError)
        {
            List<SwiftMessage> list = new List<SwiftMessage>();
            string str = messages;
            char[] chArray = new char[1]
            {
              messagesDelimiter
            };
            foreach (string message in str.Split(chArray))
            {
                if (!string.IsNullOrEmpty(message.Trim()))
                    list.Add(this.GetMessage(message, parseError));
            }
            return list;
        }

        private class _Instance
        {
            internal static readonly SwiftParser _SwiftParser = new SwiftParser();

            static _Instance()
            {
            }
        }
  }
}
